#!/usr/bin/env bash
set -Eeuo pipefail

self="$(basename "$0")"
usage() {
	cat <<-EOU
		usage: $self path/to/README.md
		   eg: $self README.md

		WARNING: if README.md has the TOC-replacement comments,
		         README.md.bak will be clobbered and the TOC will be inserted
	EOU
}

readme="${1:-}"
if ! shift || [ ! -f "$readme" ]; then usage >&2; exit 1; fi

toc="$(
	gawk '
		# ignore comments in code blocks, which are not headers but look like them
		/^```/ { ignore = !ignore }

		/^#/ && !ignore {
			level = length($1)
			$1 = ""
			gsub(/^[[:space:]]|[[:space:]]$/, "")

			++levelCounter[level]
			for (i in levelCounter) {
				if (i > level) {
					levelCounter[i] = 0
				}
			}
			prefix = levelCounter[level] ".\t"
			for (i = 1; i < level; ++i) {
				prefix = "\t" prefix
			}

			# https://github.com/thlorenz/anchor-markdown-header/blob/56f77a232ab1915106ad1746b99333bf83ee32a2/anchor-markdown-header.js#L20-L30
			hash = tolower($0)
			gsub(/ /, "-", hash)
			gsub(/[\/?!:\[\]`.,()*"'"'"';{}+=<>~\$|#@&–—]/, "", hash)
			gsub(/[。？！，、；：“”【】（）〔〕［］﹃﹄“ ”‘’﹁﹂—…－～《》〈〉「」]/, "", hash)

			printf "%s[%s](#%s)\n", prefix, $0, hash
		}
	' "$readme"
)"

toFile="${readme}.bak"
gawk -v toFile="$toFile" -v toc="$toc" '
	BEGIN { printf "" > toFile }
	/^<!-- AUTOGENERATED TOC -->$/ {
		inToc = !inToc
		seenToc = 1
		if (inToc) {
			print >> toFile
			print "" >> toFile
			print toc >> toFile
			print "" >> toFile
			print >> toFile
		}
		next
	}
	!inToc { print >> toFile }
	END { if (!seenToc) { close(toFile); printf "" > toFile } }
' "$readme"

if [ -s "$toFile" ]; then
	mv "$toFile" "$readme"
else
	rm "$toFile"
	echo "$toc"
fi
